#ifndef LIB_AX_BHP_SHD_PARSER_H
#define LIB_AX_BHP_SHD_PARSER_H
#include "libAcoustX/export.h"
#include <fstream>
#include <vector>
#include <string>
#include <complex>
#include <cmath>    // For std::isnan, std::isinf
#include <cstdint>  // For int32_t
#include <ios>      // For std::ios::binary, etc.
#include <cstring>  // For strcmp (still needed for plot_type comparison)

namespace ax {
namespace bhp {
AX_EXPORT extern double convert_pressure_2_TxLossDB(const std::complex<double>& complex_double);

/**
 * \brief Struct for storing data of acoustic toolbox SHD file (Syntax V1)
 * Struct ShdData_v1 stores Pressure provided by acoustic toolbox SHD file (Syntax V1)
 * Uses C++ containers for automatic memory management.
 */
struct AX_EXPORT ShdData
{
	int32_t record_length;
	std::string plot_type;

	int32_t Nfreq;
	std::vector<double> frequencies;
	int32_t Ntheta;
	std::vector<double> theta;
	int32_t Nsd;
	std::vector<float> tx_depths;
	int32_t Nrd;
	std::vector<float> rx_depths;
	int32_t Nrr;
	std::vector<float> rx_ranges;

	int32_t Nrx_per_range;
	double stabil_atten;
	double frequency;

	double min_tl;
	double max_tl;

	/**
	* Vector of complex<double> values
	* Data is organized as [Nfreq][Ntheta][Nsd][Nrx_per_range][Nrr]
	* Stored linearly, size = Nfreq * Ntheta * Nsd * Nrx_per_range * Nrr
	*/
	//		std::vector<::std::complex<double>> press_values;
	std::vector<std::vector<double>> tl_values;
	/**
	* Returns the index of given array associated to given value
	* @param value test value
	* @param array valid const reference to a vector
	* @returns valid array index value
	*/
	int getIndex(float value, const std::vector<float>& array) const;
	/**
	* Returns the index of given array associated to given value
	* @param value test value
	* @param array valid const reference to a vector
	* @returns valid array index value
	*/
	int getIndex(double value, const std::vector<double>& array) const;
	/**
	 * Calculates the linear index in press_values for given parameters
	 * @param freq_idx Frequency index
	 * @param theta_idx Theta index
	 * @param sd_idx Source depth index
	 * @param rd_idx Receiver depth index
	 * @param rr_idx Receiver range index
	 * @returns linear index
	 */
	int getPressureLinearIndex(int freq_idx, int theta_idx, int sd_idx, int rd_idx, int rr_idx) const;
};

class ShdReaderPrivate;
class AX_EXPORT ShdReader
{
public:
	using sptr = std::shared_ptr<ShdReader>;
	using csptr = std::shared_ptr<const ShdReader>;

	ShdReader();
	virtual ~ShdReader();

	/**
		 * Reads the SHD file (Syntax V1) and stores the data.
		 * @param filename Path to the SHD file.
		 * @return true if successful, false otherwise.
		 */
	bool readShdFile(const std::string& filename);
	/**
	 * Gets the parsed SHD data.
	 * @return Const reference to the parsed data. Data is valid only after successful readShdFile call.
	 */
	const ShdData& getShdData() const;
	/**
	 * Gets the Last Error Message.
	 * @return Const reference to the parsed data. Data is valid only after successful readShdFile call.
	 */
	std::string getLastErrorMessage() const;

protected:
	std::shared_ptr<ShdReaderPrivate> d;

private:

};

} // namespace bhp
} // namespace ax

#endif // !LIB_AX_BHP_SHD_PARSER_H
